using Senparc.Weixin.Entities;
using Senparc.Weixin.Work.AdvancedAPIs;
using WeWorkApp.Api.Models.WeChat;

namespace WeWorkApp.Api.Services
{
    /// <summary>
    /// 企业微信业务服务实现
    /// </summary>
    public class WeChatWorkService : IWeChatWorkService
    {
        private readonly ILogger<WeChatWorkService> _logger;
        private readonly IConfiguration _configuration;
        private readonly SenparcWeixinSetting _weixinSetting;

        public WeChatWorkService(
            ILogger<WeChatWorkService> logger,
            IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;
            _weixinSetting = _configuration.GetSection("SenparcWeixinSetting").Get<SenparcWeixinSetting>() 
                ?? throw new InvalidOperationException("SenparcWeixinSetting configuration is missing");
        }

        /// <summary>
        /// 获取客户详情
        /// </summary>
        /// <param name="externalUserId">外部联系人ID</param>
        /// <param name="corpId">企业ID（可选）</param>
        /// <returns></returns>
        public async Task<CustomerDetailDto> GetCustomerDetailAsync(string externalUserId, string? corpId = null)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(externalUserId))
                {
                    throw new ArgumentException("外部联系人ID不能为空", nameof(externalUserId));
                }

                _logger.LogInformation("开始获取客户详情: ExternalUserId={ExternalUserId}, CorpId={CorpId}", 
                    externalUserId, corpId);

                // 获取CorpAccessToken（这里需要根据实际情况获取）
                // 对于第三方应用，需要先获取SuiteAccessToken，然后获取CorpAccessToken
                var corpAccessToken = await GetCorpAccessTokenInternalAsync(corpId);
                if (string.IsNullOrEmpty(corpAccessToken))
                {
                    _logger.LogError("获取企业访问令牌失败");
                    throw new UnauthorizedAccessException("无法获取企业访问令牌");
                }

                // 调用企业微信API获取客户详情
                var result = await ExternalApi.GetExternalContactInfoAsync(corpAccessToken, externalUserId);

                if (result.errcode != 0)
                {
                    _logger.LogError("获取客户详情失败，错误码: {ErrorCode}, 错误信息: {ErrorMessage}", 
                        result.errcode, result.errmsg);
                    throw new Exception($"获取客户详情失败: {result.errmsg} (错误码: {result.errcode})");
                }

                // 转换为响应模型
                var response = new CustomerDetailDto
                {
                    ExternalUserId = result.external_contact.external_userid,
                    Name = result.external_contact.name ?? "未知客户",
                    Avatar = result.external_contact.avatar ?? "",
                    Type = result.external_contact.type,
                    Gender = result.external_contact.gender,
                    UnionId = result.external_contact.unionid ?? "",
                    Position = result.external_contact.position ?? "",
                    CorpName = result.external_contact.corp_name ?? "",
                    CorpFullName = result.external_contact.corp_full_name ?? "",
                    FollowUsers = result.follow_user?.Select(f => new FollowUserDto
                    {
                        UserId = f.userid,
                        Remark = f.remark ?? "",
                        Description = f.description ?? "",
                        CreateTime = f.createtime,
                        AddWay = new AddWayDto { Type = f.add_way, Scene = "" },
                        OperUserId = f.oper_userid ?? "",
                        State = f.state ?? "",
                        Tags = f.tags?.Select(t => new TagDto
                        {
                            GroupName = t.group_name ?? "",
                            TagName = t.tag_name ?? "",
                            TagId = t.tag_id ?? "",
                            Type = t.type
                        }).ToList() ?? new List<TagDto>()
                    }).ToList() ?? new List<FollowUserDto>()
                };

                _logger.LogInformation("成功获取客户详情: Name={Name}, Type={Type}, FollowUserCount={FollowUserCount}", 
                    response.Name, response.Type, response.FollowUsers?.Count ?? 0);
                return response;
            }
            catch (ArgumentException)
            {
                throw;
            }
            catch (UnauthorizedAccessException)
            {
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取客户详情时发生异常: ExternalUserId={ExternalUserId}", externalUserId);
                throw new InvalidOperationException("获取客户详情失败", ex);
            }
        }

        /// <summary>
        /// 获取SuiteAccessToken
        /// </summary>
        public async Task<string> GetSuiteAccessTokenAsync()
        {
            try
            {
                _logger.LogInformation("获取SuiteAccessToken（模拟）");
                // 这里应该调用企业微信API获取SuiteAccessToken
                // 暂时返回模拟token
                return await Task.FromResult("mock-suite-access-token");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取SuiteAccessToken时发生异常");
                throw;
            }
        }

        /// <summary>
        /// 获取CorpAccessToken
        /// </summary>
        public async Task<string> GetCorpAccessTokenAsync(string corpId, string permanentCode)
        {
            try
            {
                if (string.IsNullOrEmpty(corpId))
                {
                    throw new ArgumentException("CorpId不能为空", nameof(corpId));
                }
                if (string.IsNullOrEmpty(permanentCode))
                {
                    throw new ArgumentException("PermanentCode不能为空", nameof(permanentCode));
                }

                _logger.LogInformation("获取CorpAccessToken: CorpId={CorpId}", corpId);

                // 这里应该调用企业微信API获取CorpAccessToken
                // 暂时返回模拟token
                var accessToken = $"mock-corp-access-token-for-{corpId}";

                return await Task.FromResult(accessToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取CorpAccessToken时发生异常，CorpId: {CorpId}", corpId);
                throw;
            }
        }

        /// <summary>
        /// 保存SuiteTicket
        /// </summary>
        public async Task SaveSuiteTicketAsync(string suiteTicket)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(suiteTicket))
                {
                    throw new ArgumentException("SuiteTicket不能为空", nameof(suiteTicket));
                }

                _logger.LogInformation("保存SuiteTicket: {SuiteTicket}", suiteTicket);

                // 实际项目中应该保存到数据库或持久化存储
                // 这里暂时只记录日志
                _logger.LogInformation("SuiteTicket保存成功（模拟）");
                
                await Task.CompletedTask;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存SuiteTicket时发生异常");
                throw;
            }
        }

        /// <summary>
        /// 获取JSSDK配置
        /// </summary>
        public async Task<JsSdkConfigDto> GetJsSdkConfigAsync(string url, string? corpId, string? agentId, List<string>? jsApiList, bool debug = false)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(url))
                {
                    throw new ArgumentException("URL不能为空", nameof(url));
                }

                // 使用传入参数或回退到配置
                var effectiveCorpId = !string.IsNullOrWhiteSpace(corpId) ? corpId : _weixinSetting.WeixinCorpId;
                var effectiveAgentId = !string.IsNullOrWhiteSpace(agentId) ? agentId : _configuration["SenparcWeixinSetting:AgentId"] ?? "1000001";

                // TODO: 根据实际情况获取jsapi_ticket并计算signature
                var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                var nonceStr = Guid.NewGuid().ToString("N")[..16];

                // 暂时返回模拟配置，透传部分参数
                return await Task.FromResult(new JsSdkConfigDto
                {
                    CorpId = effectiveCorpId ?? string.Empty,
                    AgentId = effectiveAgentId,
                    Timestamp = timestamp,
                    NonceStr = nonceStr,
                    Signature = "mock-signature",
                    JsApiList = jsApiList ?? new List<string>(),
                    Debug = debug
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取JSSDK配置时发生异常，URL: {Url}, CorpId: {CorpId}", url, corpId);
                throw;
            }
        }

        /// <summary>
        /// 内部方法：获取CorpAccessToken
        /// </summary>
        private async Task<string> GetCorpAccessTokenInternalAsync(string? corpId)
        {
            // 这里需要根据实际业务逻辑获取CorpAccessToken
            // 对于第三方应用，需要先获取企业的永久授权码
            // 这里暂时返回模拟token，实际项目中需要完善
            
            if (string.IsNullOrEmpty(corpId))
            {
                throw new ArgumentException("CorpId 不能为空");
            }

            // 模拟获取永久授权码的逻辑
            var permanentCode = "mock-permanent-code"; // 需要从数据库获取
            
            return await GetCorpAccessTokenAsync(corpId, permanentCode);
        }
    }
}